#include <iostream>
#include <boost/program_options.hpp>

#include "protonos8.hpp"

int
main(int argc, char* argv[])
{
	try
	{
		namespace po = boost::program_options;

		po::options_description desc("Allowed options");
		desc.add_options()
			("help", "produce help message")
			("host", po::value<std::string>()->default_value("localhost"), "server name")
			("port", po::value<std::string>()->default_value("9990"), "socket port")
			("location", po::value<int>()->default_value(0), "piggyback location")
			("address", po::value<std::string>()->default_value("0x0"), "address (hex)")
			("write", "do write op instead of read")
			("value", po::value<std::string>()->default_value("0x0"), "value (hex)")
			("continuous", "do forever")
			("quiet", "be quiet")
		;

		po::variables_map vm;
		po::store(po::parse_command_line(argc, argv, desc), vm);
		po::notify(vm);    

		if (vm.count("help")) {
			std::cout << desc << "\n";
			return 1;
		}

		bool writeop = (vm.count("write")) ? true : false;
		bool continuous = (vm.count("continuous")) ? true : false;
		bool quiet = (vm.count("quiet")) ? true : false;

		unsigned pb_loc = vm["location"].as<int>();
		uint32_t address = std::strtoul(vm["address"].as<std::string>().c_str(), NULL, 16);
		uint32_t value = std::strtoul(vm["value"].as<std::string>().c_str(), NULL, 16);
		std::size_t total = 0;

		std::cout << "host " <<
			vm["host"].as<std::string>() << ":" <<
			vm["port"].as<std::string>() << std::endl;

		protonos8::client client(vm["host"].as<std::string>().c_str(), vm["port"].as<std::string>().c_str());

		if (continuous)
			std::cout << "To stop test press Ctrl-C ...\n";

		do {
			protonos8::ack_result result;

			if (!quiet) {
				std::cout << ((writeop) ? "write" : "read") << ":";
				std::cout << " location=" << vm["location"].as<int>() << ",";
				std::cout << " address=0x" << std::hex << address << std::dec << ",";
			}

			if (writeop) {
				result = client.raw_write(pb_loc, address, value);
				if (!quiet || result != protonos8::success) {
					std::cout << " value=0x" << std::hex << value << std::dec << ",";
					std::cout << " raw_write ack_result=" << (int)result << ",";
				}
			} else {
				result = client.raw_read(pb_loc, address, value);
				if (!quiet || result != protonos8::success) {
					std::cout << " raw_read ack_result=" << (int)result << ";";
					std::cout << " value=0x" << std::hex << value << std::dec << ";";
				}
			}

			if (continuous)
				std::cout << " total=" << total++ << "\r";

		} while (continuous);

		std::cout << std::endl;

		return 0;

	} catch (std::exception& e) {
		std::cerr << "Exception: " << e.what() << "\n";
	}

	return 0;
}
